from qturboframe.lib.utils.by import By
from qturboframe.lib.webdriver.exceptions import SeleniumError
from qturboframe.lib.utils.assertion import Assertion
from qturboframe.lib.report.log import logger
from qturboframe.public_ui.jresui2.button import Button

from .base_element import BaseElement


class Message(BaseElement):
    '''
    Jres2.0 消息框操作类
    
    :Attributes:
     - _driver: 控件所在的当前webdriver对象
     - _element: 控件元素webelement对象, 是class包含m-message-position的tag
     - timeout: 步骤操作的超时时间

    :Example:
     - 例1: Message(webelement)
     - 例2: Message(text = '登录')
     - 例3: Message({By.CLASS_NAME:'class_name','text':'文本信息'})
     - 例4: Message({By.CLASS_NAME:'class_name','text':'文本信息'}, father=driver)
     - 例5: Message({By.CLASS_NAME:'class_name','text':'文本信息'}, father=webelement)
    '''

    def __init__(self, element_para, father=None, timeout=5):
        if isinstance(element_para, str):
            message_title = self.__get_message_element(father, element_para, timeout)
            if message_title:
                message = message_title.find_element_by_attribute("xpath",".//ancestor::*[contains(@class,'m-message-positon')]", timeout=timeout)
                super().__init__(message, father, timeout)
                return 
            raise SeleniumError("没有找到标题为‘{}’的提示框".format(element_para))
        elif isinstance(element_para, dict) and By.TEXT in element_para:
            message_title = self.__get_message_element(father, element_para.get(By.TEXT), timeout)
            if message_title:
                message = message_title.find_element_by_attribute("xpath",".//ancestor::*[contains(@class,'m-message-positon')]", timeout=timeout)
                super().__init__(message, father, timeout)
                return
            raise SeleniumError("没有找到标题为‘{}’的提示框".format(element_para))
        else:
            super().__init__(element_para, father, timeout)
            
            if 'm-message-header' in self._element.get_attribute("class"):
                xpath = ".//ancestor::*[contains(@class,'m-message-positon')]"
                self._element = self._element.find_element_by_attribute("xpath", xpath, timeout=timeout)

    def __get_message_element(self, father, text, timeout):
        xpath = ".//*[@class='m-message-positon']//*[@class='m-message-header' and @title='{}']".format(text.strip())
        message_title = father.find_first_displayed_element(By.XPATH, xpath, timeout=timeout)
        return message_title

    def exist(self):
        '''
        判断消息框是否存在

        :Returns:
            存在则返回True，不存在则返回False

        :Example:
         - 例: message.exist()
        '''
        if self._element:
            return True
        else:
            return False

    def get_text(self):
        '''
        获取消息框中的消息文本

        :Returns:
            返回消息文本

        :Example:
         - 例: message.get_text()
        '''
        try:
            content_div = self._element.find_element_by_attribute(
                'css selector', 'div.m-message-body div.m-body-words', timeout=self.timeout)
            return content_div.text
        except Exception as msg:
            logger.warn(str(msg))
            return None

    def close(self):
        '''
        关闭消息框

        :Example:
         - 例: message.close()
        '''
        try:
            close_btn = self._element.find_element_by_attribute(
                'css selector', 'div.m-message-header>span', timeout=self.timeout)
            close_btn.secure_click()
        except Exception as msg:
            logger.error(str(msg))
            raise SeleniumError('消息框关闭失败！')

    def check(self, ui_expect):
        '''
        检查信息内容

        :Args:
         - ui_expect: 界面期望值

        :Raises:
            检查不通过抛出SeleniumError异常

        :Example:
         - 例: message.check('新增成功')
        '''
        ui_value = self.get_text()
        try:
            Assertion(ui_expect).check_string(ui_value)
        except AssertionError:
            raise SeleniumError('界面取值为{}，期望值为{}，弹出的信息提示与期望不一致！'.format(
            ui_value, ui_expect))

    def confirm(self):
        confirm = self._element.find_element_by_attribute("xpath",".//*[@id='buttonOK']", timeout=self.timeout)
        confirm.click()

    def click_continue(self):
        continue_button = Button({By.TEXT, "继续"}, father=self._element, timeout=self.timeout)
        BaseElement(continue_button).click()

    def click_close(self):
        close_button = Button({By.TEXT, "关闭"}, father=self._element, timeout=self.timeout)
        BaseElement(close_button).click()